/*
Danger from the Deep - Open source submarine simulation
Copyright (C) 2003-2006  Thorsten Jordan, Luis Barrancos and others.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

// (physics) physics formulas
// subsim (C)+(W) SEE LICENSE

#include <vector>
#include "physics.h"

const double math::DELTA = 1e-5; // For IS_ZERO

// math - Floating-Point
bool math::IS_ZERO (double value) {
	return (value < DELTA && value > -DELTA);
}

// math - Statistics
double math::average (std::vector<double>& values) {
	double avg = 0.0;
	for (unsigned int i=0; i<values.size(); i++)
		avg += values[i];
	return avg / values.size();
}

double math::weighted_average (std::vector<double>& values, std::vector<double>& weights) {
	if (values.size() != weights.size())
		throw error("value and weights vectors must have same size");

	double avg = 0.0;
	for (unsigned int i=0; i<values.size(); i++)
		avg += (values[i] * weights[i]);
	return avg / values.size();
}


// Physics - Motion
void physics::new_position(vector3& position, vector3& velocity, vector3& acceleration, double delta) {
	position += velocity * delta + acceleration * (delta * delta / 2);
}
void physics::new_velocity(vector3& velocity, vector3& acceleration, double delta) {
	velocity += acceleration * delta;
}

// Physics - Forces
vector3 physics::net_force(std::vector<vector3>& forces) {
	vector3 net;
	for (unsigned int i=0; i<forces.size(); i++)
		net += forces[i];
	return net;
}

// Physics - Densities
double physics::net_density (std::vector<double>& density, std::vector<double>& occupacy) {
	return math::weighted_average(density, occupacy);
}

